﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using AutoLoL.Entities;
using AutoLoL.Logic.Utils;
using System.Windows.Input;
using AutoLoL.Shared;

namespace AutoLoL.Logic
{
    [DataContract]
    public class UserSettings : INotifyPropertyChanged
    {
        #region Default values
        private static readonly List<ChatItem> DEFAULT_CHAT_ITEMS = new List<ChatItem>()
        {
            new ChatItem(1, "Miss")
            {
                Children = new List<ChatItem>()
                {
                    new ChatItem(1, "Miss TOP! Care!"),
                    new ChatItem(2, "Miss MID! Care!"),
                    new ChatItem(3, "Miss BOT! Care!"),
                    new ChatItem(4, ""),
                    new ChatItem(5, ""),
                    new ChatItem(6, "")
                }
            },
            new ChatItem(2, "Re")
            {
                Children = new List<ChatItem>()
                {
                    new ChatItem(1, "Re TOP!"),
                    new ChatItem(2, "Re MID!"),
                    new ChatItem(3, "Re BOT!"),
                    new ChatItem(4, ""),
                    new ChatItem(5, ""),
                    new ChatItem(6, "")
                }
            },
            new ChatItem(3, "Timers")
            {
                Children = new List<ChatItem>()
                {
                    new ChatItem(1, "Ward: {t} > {t:180}"),
                    new ChatItem(2, "Golem: {t} > {t:300}"),
                    new ChatItem(3, "Lizard: {t} > {t:300}"),
                    new ChatItem(4, "Dragon: {t} > {t:360}"),
                    new ChatItem(5, "Baron: {t} > {t:420}"),
                    new ChatItem(6, "")
                }
            },
            new ChatItem(4, ""),
            new ChatItem(5, ""),
            new ChatItem(6, "/all Automate masteries, login and chat with AutoLoL - http://autolol.codeplex.com/"),
        };

        private static readonly UserSettings DEFAULT_USER_SETTINGS = new UserSettings()
        {
            LolDirectory = string.Empty,
            IsAutorunEnabled = false,
            
            IsManualReturnEnabled = false,

            IsAutoChatEnabled = false,
            AutoChatModifierKey = Constants.AUTOCHAT_MODIFIER_KEYS.Keys.First(),
            AutoChatKeys = Constants.AUTOCHAT_KEYS.Keys.First(),

            LolUsername = string.Empty,
            LolPasswordEncrypted = string.Empty,
            IsAutoLoginEnabled = true,

            IsMinimizeToTrayEnabled = false,

            ChatItems = DEFAULT_CHAT_ITEMS,
            FirstRun = true
        };
        #endregion

        private static string FILENAME = Environment.UserName.ToLower() + ".lol2";

        private static UserSettings _instance;
        public static UserSettings Instance
        {
            get
            {
                if (_instance == null)
                {
                    try
                    {
                        // Load settings from file
                        string path = Path.Combine(Constants.APPLICATION_DIRECTORY, FILENAME);

                        if (File.Exists(path))
                        {
                            using (FileStream reader = new FileStream(path, FileMode.Open, FileAccess.Read))
                            {
                                DataContractSerializer ser = new DataContractSerializer(typeof(UserSettings));
                                _instance = (UserSettings)ser.ReadObject(reader);
                            }
                        }
                    }
                    catch { if (Debugger.IsAttached) throw; }

                    if (_instance == null)
                    {
                        // Load and save default settings
                        _instance = DEFAULT_USER_SETTINGS;

                        try { _instance.Save(); }
                        catch { if (Debugger.IsAttached) throw; }
                    }
                }

                return _instance;
            }
        }

        public void Save()
        {
            string path = Path.Combine(Constants.APPLICATION_DIRECTORY, FILENAME);

            using (FileStream writer = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                DataContractSerializer ser = new DataContractSerializer(typeof(UserSettings));
                ser.WriteObject(writer, Instance);
            }
        }

        private string _lolDirectory;
        private bool _isAutorunEnabled;

        private bool _isManualReturnEnabled;

        private bool _isAutoChatEnabled;
        private int _autoChatModifierKey;
        private int[] _autoChatKeys;

        private string _lolUsername;
        private string _lolPasswordEncrypted;
        private bool _isAutoLoginEnabled;

        private bool _isMinimizeToTrayEnabled;

        private List<ChatItem> _chatItems;
        private bool _firstRun;

        [DataMember]
        public string LolDirectory
        {
            get { return _lolDirectory; }
            set
            {
                _lolDirectory = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.LolDirectory).Name);
            }
        }

        [DataMember]
        public bool IsAutorunEnabled
        {
            get { return _isAutorunEnabled; }
            set
            {
                _isAutorunEnabled = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.IsAutorunEnabled).Name);
            }
        }

        [DataMember]
        public bool IsManualReturnEnabled
        {
            get { return _isManualReturnEnabled; }
            set
            {
                _isManualReturnEnabled = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.IsManualReturnEnabled).Name);
            }
        }

        [DataMember]
        public bool IsAutoChatEnabled
        {
            get { return _isAutoChatEnabled; }
            set
            {
                _isAutoChatEnabled = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.IsAutoChatEnabled).Name);
            }
        }

        [DataMember(IsRequired = false)]
        public int[] AutoChatKeys
        {
            get { return _autoChatKeys; }
            set
            {
                _autoChatKeys = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.AutoChatKeys).Name);
            }
        }

        [DataMember(IsRequired = false)]
        public int AutoChatModifierKey
        {
            get { return _autoChatModifierKey; }
            set
            {
                _autoChatModifierKey = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.AutoChatModifierKey).Name);
            }
        }

        [DataMember]
        public string LolUsername
        {
            get { return _lolUsername; }
            set
            {
                _lolUsername = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.LolUsername).Name);
            }
        }

        [DataMember]
        public string LolPasswordEncrypted
        {
            get { return _lolPasswordEncrypted; }
            set
            {
                _lolPasswordEncrypted = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.LolPasswordEncrypted).Name);
            }
        }

        [DataMember]
        public bool IsAutoLoginEnabled
        {
            get { return _isAutoLoginEnabled; }
            set
            {
                _isAutoLoginEnabled = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.IsAutoLoginEnabled).Name);
            }
        }

        [DataMember]
        public bool IsMinimizeToTrayEnabled
        {
            get { return _isMinimizeToTrayEnabled; }
            set
            {
                _isMinimizeToTrayEnabled = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.IsMinimizeToTrayEnabled).Name);
            }
        }

        [DataMember]
        public List<ChatItem> ChatItems
        {
            get { return _chatItems; }
            set
            {
                _chatItems = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.ChatItems).Name);
            }
        }

        [DataMember]
        public bool FirstRun
        {
            get { return _firstRun; }
            set
            {
                _firstRun = value;
                OnPropertyChanged(TypeManager.GetProperty<UserSettings>(x => x.FirstRun).Name);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
